﻿// This file is part of GEOTRON.

// GEOTRON is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// The GEOTRON library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with GEOTRON.  If not, see <http://www.gnu.org/licenses/>.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Diagnostics;

using System.IO;
using System.Xml;

namespace Geotron
{

    public enum ResolutionInstruction
    {
        OnlyPostcode
    }

    /// <summary>
    /// Contains functions for resolving addresses / postcodes
    /// </summary>
    public static partial class GeoResolve
    {
        /// <summary>Internal flag used for checking whether the class
        /// has been instantiated.</summary>
        static private bool isInitialized { set; get; }

        /// <summary>
        /// Loads the countries from the CountryData.xml file and instantiates them.
        /// </summary>
        static public void Initialize(ResolutionInstruction ResolutionArgument)
        {

            if (ResolutionArgument != ResolutionInstruction.OnlyPostcode) throw new NotImplementedException("Only postcode resolution is offered in this build.");

            XmlReaderSettings Settings = new XmlReaderSettings();
            Settings.ConformanceLevel = ConformanceLevel.Document;
            Settings.IgnoreComments = true;
            Settings.IgnoreWhitespace = true;

            Countries = new List<Country>();

            using (XmlReader Reader = XmlReader.Create("CountryData.xml",Settings))
            {
                Reader.ReadStartElement("CountryData");
                Reader.ReadStartElement("SchemaVersion");
                if(Reader.ReadString() != "2") throw new Exception("Incompatable or corrupt CountryData.xml file!");
                Reader.ReadEndElement();
                Reader.ReadStartElement("Countries");
                int CountryCounter = 0;
                while(Reader.Read())
                {
                    if(Reader.IsStartElement())
                    {
                        var Country = new Country();
                        try
                        {
                            CountryCounter++;  Trace.Write("Reading country " + CountryCounter.ToString() + "...");

                            Country.Name = ReadCountryFileNode("Name", Reader);
                            Country.ShortName = ReadCountryFileNode("ShortName",Reader);
                            
                            string FormatTemp = ReadCountryFileNode("PostcodeFormat",Reader).Replace(" ","");
                            string[] FormatArray = FormatTemp.Split('|');
                            for(int i=0; i<FormatArray.Count(); i++) Country.PostcodeFormats.Add(FormatArray[i]);

                            Reader.ReadStartElement("DataSources");
                            if (ReadCountryFileNode("GNS",Reader) == "yes") Country.GnsFile = true;
                            else Country.GnsFile = false;
                            if (ReadCountryFileNode("PostCodes", Reader) == "yes") Country.PostCodeFile = true;
                            else Country.PostCodeFile = false;
                            Reader.ReadEndElement();

                            Countries.Add(Country);

                            Trace.WriteLine("Finished reading "+Country.Name);
                        }
                        catch (Exception e)
                        {
                            Trace.WriteLine(e);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Reads the node with specified name. Kills the ingestion if there is a validation error.
        /// </summary>
        /// <param name="NodeName">The name of the node to read.</param>
        /// <param name="Reader">The XML reader being used to parse the file</param>
        /// <returns>A string containing the text inside the node.</returns>
        static private string ReadCountryFileNode(string NodeName, XmlReader Reader)
        {
            Trace.Write("ReadCountryFileNode: Reading '"+NodeName+"'...");
            string Return = "n/a";
            try
            {
                Reader.ReadStartElement(NodeName);
                Return = Reader.ReadString();
                Reader.ReadEndElement();
            }
            catch (Exception e) { Trace.WriteLine("Tried to parse a country without a '" + NodeName + "' element from the CountryData.xml file."); }
            Trace.WriteLine("Done");
            return Return;
        }
    }
}
